﻿using System.Collections;
using WHC.Security.Common;

using WHC.Security.Entity;
using WHC.Security.IDAL;
using System;
using System.Collections.Generic;

namespace WHC.Security.BLL
{
    public class Role : BaseBLL<RoleInfo>
	{
		private static int m_AdminID = -99;
		private IRole roleDal;

		public Role() : base()
		{
			this.roleDal = null;
			this.roleDal = (IRole) baseDal;
		}

		public void AddFunction(int functionID, int roleID)
		{
			this.roleDal.AddFunction(functionID, roleID);
		}

		public void AddOU(int ouID, int roleID)
		{
			roleDal.AddOU(ouID, roleID);
		}

		public void AddUser(int userID, int roleID)
		{
			this.FillAdminID();
			if (roleID == m_AdminID)
			{
				new User().EnabledExpire(userID);
			}
			roleDal.AddUser(userID, roleID);
		}

		internal bool AdminHasUser()
		{
			this.FillAdminID();
			User user = new User();
			return (user.GetSimpleUsersByRole(m_AdminID).Count > 0);
		}

		private void CanRemoveFromAdmin(int roleID)
		{
			this.FillAdminID();
			if ((roleID == m_AdminID) && (this.GetAdminSimpleUsers().Count < 2))
			{
				throw new MyException("管理员角色至少需要包含一个用户！");
			}
		}

		public override bool  Delete(string key)
        {
            if (Convert.ToInt32(key) == m_AdminID)
			{
				throw new MyException("管理员角色不能被删除！");
			}
			return baseDal.DeleteByKey(key);
		}

		private void FillAdminID()
		{
			if (m_AdminID == -99)
			{
				RoleInfo roleByName = this.GetRoleByName("管理员");
				if (roleByName != null)
				{
					m_AdminID = roleByName.ID;
				}
			}
		}

		internal List<int> GetAdminOUIDs()
		{
			this.FillAdminID();
			List<OUInfo> oUsByRole = new OU().GetOUsByRole(m_AdminID);
            List<int> list2 = new List<int>();
			foreach (OUInfo info in oUsByRole)
			{
				list2.Add(info.ID);
			}
			return list2;
		}

        internal List<SimpleUserInfo> GetAdminSimpleUsers()
		{
			this.FillAdminID();
			User user = new User();
			List<SimpleUserInfo> simpleUsersByRole = user.GetSimpleUsersByRole(m_AdminID);
			int count = simpleUsersByRole.Count;
			if (count < 2)
			{
				OU ou = new OU();
				foreach (OUInfo info in ou.GetOUsByRole(m_AdminID))
				{
                    List<SimpleUserInfo> simpleUsersByOU = user.GetSimpleUsersByOU(info.ID);
					if (simpleUsersByOU.Count > 0)
					{
						simpleUsersByRole.Add(simpleUsersByOU[0]);
						count++;
						if (simpleUsersByOU.Count > 1)
						{
							simpleUsersByRole.Add(simpleUsersByOU[1]);
							count++;
						}
						if (count > 1)
						{
							return simpleUsersByRole;
						}
					}
				}
			}
			return simpleUsersByRole;
		}

		public RoleInfo GetRoleByName(string roleName)
		{
			return this.roleDal.FindSingle("Name='" + roleName + "'");
		}

		public List<RoleInfo> GetRolesByFunction(int functionID)
		{
			return this.roleDal.GetRolesByFunction(functionID);
		}

        public List<RoleInfo> GetRolesByOU(int ouID)
		{
			return this.roleDal.GetRolesByOU(ouID);
		}

        public List<RoleInfo> GetRolesByUser(int userID)
		{
			List<RoleInfo> rolesByUser = this.roleDal.GetRolesByUser(userID);
			ArrayList list2 = new ArrayList();
			foreach (RoleInfo info in rolesByUser)
			{
				list2.Add(info.ID);
			}

			OU ou = new OU();
			foreach (OUInfo info2 in ou.GetOUsByUser(userID))
			{
				foreach (RoleInfo info3 in this.roleDal.GetRolesByOU(info2.ID))
				{
					if (list2.IndexOf(info3.ID) < 0)
					{
						rolesByUser.Add(info3);
						list2.Add(info3.ID);
					}
				}
			}
			return rolesByUser;
		}

		public void RemoveFunction(int functionID, int roleID)
		{
			this.roleDal.RemoveFunction(functionID, roleID);
		}

		public void RemoveOU(int ouID, int roleID)
		{
			this.FillAdminID();
			if (roleID == m_AdminID)
			{
				User user = new User();
				List<SimpleUserInfo> simpleUsersByRole = user.GetSimpleUsersByRole(m_AdminID);
				if (simpleUsersByRole.Count < 1)
				{
					simpleUsersByRole.Clear();
					List<UserInfo> usersByOU = user.GetUsersByOU(ouID);
					if (usersByOU.Count > 0)
					{
						usersByOU.Clear();
						bool flag = false;
						List<OUInfo> oUsByRole = new OU().GetOUsByRole(m_AdminID);
						foreach (OUInfo info in oUsByRole)
						{
							if ((info.ID != ouID) && (user.GetSimpleUsersByOU(info.ID).Count > 0))
							{
								flag = true;
								break;
							}
						}
						oUsByRole.Clear();
						if (!flag)
						{
							throw new MyException("管理员角色至少需要包含一个用户！");
						}
					}
				}
			}
			roleDal.RemoveOU(ouID, roleID);
		}

		public void RemoveUser(int userID, int roleID)
		{
			this.CanRemoveFromAdmin(roleID);
			this.roleDal.RemoveUser(userID, roleID);
		}

		public override bool  Update(RoleInfo obj, string primaryKeyValue)
		{
			RoleInfo info = (RoleInfo) obj;
			if (info.ID == m_AdminID)
			{
				info.Name = "管理员";
			}
            return base.Update(info, primaryKeyValue);
		}
	}
}